import re

from django.shortcuts import render
from rest_framework import status
from rest_framework.response import Response
from rest_framework_simplejwt.exceptions import TokenError, InvalidToken
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet, GenericViewSet, mixins
from rest_framework.permissions import IsAuthenticated
from users.permissions import *
from shop.settings import MEDIA_ROOT
import os
from django.http import FileResponse
from users.models import User
from users.serializers import UserSerializer


class RegisterView(APIView):
    def post(self, request):
        # 1.接受用户参数
        username = request.data.get('username')
        password = request.data.get('password')
        email = request.data.get('email')
        password_confirmation = request.data.get('password_confirmation')
        # 参数校验 （校验所有参数是否为空）
        if not all([username, password, email, password_confirmation]):
            return Response({'message': '参数不能为空'}, status=status.HTTP_400_BAD_REQUEST)
        # 校验用户是否注册
        # 查询模型的数据集，然后通过username进行判断是否存在,
        if User.objects.filter(username=username).exists():
            return Response({'message': '用户已经注册'}, status=status.HTTP_400_BAD_REQUEST)
        # 校验两次密码是否一致
        if password != password_confirmation:
            return Response({'error': '两次密码不一致'}, status=status.HTTP_400_BAD_REQUEST)
        # 对密码长度进行校验
        if not 6 < len(password) < 18:
            return Response({'error': '密码长度为6-17位'}, status=status.HTTP_400_BAD_REQUEST)

        # 校验邮箱
        if User.objects.filter(email=email).exists():
            return Response({'error': '邮箱已存在'}, status=status.HTTP_400_BAD_REQUEST)
        if not re.match(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', email):
            return Response({'error': '邮箱格式不正确'}, status=status.HTTP_400_BAD_REQUEST)
        # 创建用户
        obj = User.objects.create(username=username, password=password, email=email)
        res = {
            'username': obj.username,
            'email': obj.email,
            'id': obj.id
        }

        return Response(res, status=status.HTTP_201_CREATED)


"""重写登录"""


class Login(TokenObtainPairView):
    """
    自定义登录功能，设置一些返回的结果
    """

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
        except TokenError as e:
            raise InvalidToken(e.args[0])

        # 获取序列化后校验的数据
        result = serializer.validated_data
        # 在其中添加mobile字段的返回结果
        # 注意这个mobil是个字典，所以这家添加数据
        result['id'] = serializer.user.id
        result['mobile'] = serializer.user.mobile
        result['email'] = serializer.user.email
        result['username'] = serializer.user.username
        # 在返回的数据中设置token 也即是从序列化后的数据中弹出这个字敦对应的数据
        result['token'] = result.pop('access')
        return Response(result, status=status.HTTP_200_OK)


"""获取用户列表"""


class UserView(GenericViewSet, mixins.RetrieveModelMixin):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    # 权限配置
    # permission_classes = [IsAuthenticated,IsOwnerOrRead0nly]

    # 上传头像
    def upload_avatar(self, request, *args, **kwargs):
        avatar = request.FILES.get('avatar')
        # 校验图片是否存在啊
        if not avatar:
            return Response({'code': '文件不存在'}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
        # 校验图片大小是否合适
        if avatar.size > 1024 * 300:
            return Response({"code": "图片大小超出"}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
        # 保存文件
        user = self.get_object()
        # 进行序列化，其中只需要对avatar进行序列化
        ser = self.get_serializer(user, data={'avatar': avatar}, partial=True)
        # 序列化后进行校验
        ser.is_valid(raise_exception=True)
        # 进行数据更新
        ser.save()
        # 上传成功返回
        return Response({"url": ser.data['avatar']})


# 图片获取
class FileView(APIView):
    def get(self, requests, name):
        path = MEDIA_ROOT / name
        if os.path.isfile(path):
            # 使用django中的问价返回
            return FileResponse(open(path, 'rb'))
        return Response({'code': '没有找到文件'}, status=status.HTTP_400_BAD_REQUEST)
